home *** CD-ROM | disk | FTP | other *** search
- #include "idcmp.h"
- #include "drawwin.h"
- #include "gadgets.h"
- #include "loadsave.h"
- #include "menu.h"
- #include "toolwin.h"
- #include "arexx.h"
- #include "fractal.h"
-
- #include<dos/rdargs.h>
-
- #include<string.h>
- #include<stdio.h>
-
- #include<clib/dos_protos.h>
- #include<clib/exec_protos.h>
- #include<clib/gadtools_protos.h>
- #include<clib/graphics_protos.h>
- #include<clib/intuition_protos.h>
-
- static void doGadgetUp(struct Window*, UWORD, struct Gadget*);
- static int doMenuPick(struct Window*, UWORD);
- static int doARexx(struct RexxMsg*, struct Window*);
-
- static void new(struct Window*);
-
- static int isCommand(char*, char*, char*, LONG*);
- static void freeCommand(void);
-
- /* Our message handling code */
- void handleIDCMP()
- {
- char* text = "Hello World!";
- int going = TRUE;
- int drawing = FALSE;
- ULONG drawsig, toolsig, arexxsig, gotsig;
- struct Window* drawwin = getDrawWin();
- drawsig = 1 << drawwin->UserPort->mp_SigBit;
- arexxsig = getARexxSig();
- while(going)
- {
- struct IntuiMessage* intuimsg;
- /* Only include tool window signal mask if window is open */
- toolsig = getToolSig();
- /* Wait for messages to arrive */
- gotsig = Wait(drawsig | toolsig | arexxsig);
- /* Messages have arrived: loop through all of them */
- /* Check messages from the drawing window first */
- if(gotsig & drawsig)
- {
- while(intuimsg = GT_GetIMsg(drawwin->UserPort))
- {
- /* Copy the important bits of the message */
- ULONG class = intuimsg->Class;
- UWORD code = intuimsg->Code;
- WORD mousex = intuimsg->MouseX;
- WORD mousey = intuimsg->MouseY;
- /* Reply when finished copying bits from message */
- GT_ReplyIMsg(intuimsg);
- /* Act on this message... */
- switch(class)
- {
- case IDCMP_MOUSEBUTTONS:
- switch(code)
- {
- case SELECTDOWN:
- drawing = TRUE;
- break;
- case SELECTUP:
- drawing = FALSE;
- break;
- }
- /* break; omitted so we draw on click, too */
- case IDCMP_MOUSEMOVE:
- if(drawing)
- {
- Move(drawwin->RPort, mousex, mousey);
- Text(drawwin->RPort, text, strlen(text));
- setModified(TRUE);
- }
- break;
- case IDCMP_MENUPICK:
- going = doMenuPick(drawwin, code);
- drawwin = getDrawWin();
- drawsig = 1 << drawwin->UserPort->mp_SigBit;
- break;
- }
- }
- }
- /* Now check messages from the tool window */
- if(going && (gotsig & toolsig))
- {
- struct Window* toolwin = getToolWin();
- while(toolwin && (intuimsg = GT_GetIMsg(toolwin->UserPort)))
- {
- /* Copy the important bits of the message */
- ULONG class = intuimsg->Class;
- UWORD code = intuimsg->Code;
- APTR iaddr = intuimsg->IAddress;
- /* Reply when finished copying bits from message */
- GT_ReplyIMsg(intuimsg);
- /* Act on this message... */
- switch(class)
- {
- case IDCMP_CLOSEWINDOW:
- closeToolWin();
- /* Update our local toolwin, so we stop loop */
- toolwin = NULL;
- uncheckToolBar(drawwin);
- break;
- case IDCMP_REFRESHWINDOW:
- /* You *MUST* remember to ask for and handle these refresh messages */
- GT_BeginRefresh(toolwin);
- GT_EndRefresh(toolwin, TRUE);
- break;
- case IDCMP_GADGETUP:
- doGadgetUp(drawwin, code, (struct Gadget*)iaddr);
- break;
- case IDCMP_MENUPICK:
- going = doMenuPick(drawwin, code);
- /* Update our local toolwin, so we stop loop */
- toolwin = getToolWin();
- drawwin = getDrawWin();
- drawsig = 1 << drawwin->UserPort->mp_SigBit;
- break;
- }
- }
- }
- /* Now check messages from the ARexx port */
- if(going && (gotsig & arexxsig))
- {
- struct RexxMsg* msg;
- while(going && (msg = getARexxMsg()))
- going = doARexx(msg, drawwin);
- }
- }
- }
-
- /* Process IDCMP_GADGETUP event */
- static void doGadgetUp(struct Window* drawwin, UWORD code, struct Gadget* gad)
- {
- switch(gad->GadgetID)
- {
- case MYBUT_ID:
- /* Our button was clicked! Set foreground to next pen colour */
- nextFgPen(drawwin);
- break;
- case MYPAL_ID:
- /* Our palette gadget was clicked! Set foreground to gadget colour */
- setFgPen(drawwin, code);
- break;
- }
- }
-
- /* Process IDCMP_MENUPICK event */
- static int doMenuPick(struct Window* drawwin, UWORD code)
- {
- UWORD menuCode, menuNumber, itemNumber;
- /* Loop over all the menu selections in the menu code */
- struct MenuItem* item;
- for(menuCode = code;
- menuCode != MENUNULL;
- menuCode = item->NextSelect)
- {
- item = ItemAddress(drawwin->MenuStrip, menuCode);
- /* Extract the menu number and menu item number from the menu code */
- menuNumber = MENUNUM(menuCode);
- itemNumber = ITEMNUM(menuCode);
- /* Now decide what to do based on what menu item was selected */
- switch(menuNumber)
- {
- case 0: /* Project menu */
- switch(itemNumber)
- {
- case 0: /* Load */
- {
- struct EasyStruct myreq = { sizeof(struct EasyStruct),
- 0,
- "Overwrite Confirmation",
- "Do you really wish to overwrite the current image?",
- "Yes|No" };
- /* If the image isn't modified we don't need to ask... */
- if(!isModified() || EasyRequest(drawwin, &myreq, NULL))
- {
- return load();
- }
- }
- break;
- case 1: /* Save */
- save();
- break;
- case 3: /* New (item 2 is the bar!) */
- {
- struct EasyStruct myreq = { sizeof(struct EasyStruct),
- 0,
- "Erase Confirmation",
- "Do you really wish to clear the current image?",
- "Yes|No" };
- /* If the image isn't modified we don't need to ask... */
- if(!isModified() || EasyRequest(drawwin, &myreq, NULL))
- {
- new(drawwin);
- }
- }
- break;
- case 5: /* Quit (item 4 is the bar!) */
- {
- struct EasyStruct myreq = { sizeof(struct EasyStruct),
- 0,
- "Exit Confirmation",
- "Do you really wish to quit?",
- "Yes|No" };
- /* If the image isn't modified we don't need to ask... */
- if(!isModified() || EasyRequest(drawwin, &myreq, NULL))
- return FALSE;
- }
- break;
- }
- break;
- case 1: /* Pen menu */
- switch(itemNumber)
- {
- case 0: /* Next */
- nextFgPen(drawwin);
- break;
- case 1: /* Prev */
- prevFgPen(drawwin);
- break;
- case 3: /* Reset (item 2 is the bar!) */
- resetFgPen(drawwin);
- break;
- }
- break;
- case 2: /* Tools menu */
- switch(itemNumber)
- {
- case 0: /* Screen Bar */
- ShowTitle(drawwin->WScreen, item->Flags & CHECKED);
- break;
- case 1: /* Tool Bar */
- /* Do the open or close */
- if(item->Flags & CHECKED)
- {
- /* If the open fails, stop immediately */
- if(!openToolWin())
- return FALSE;
- }
- else
- closeToolWin();
- break;
- case 3: /* Fractal (item 2 is the bar!) */
- drawFractal(drawwin);
- }
- }
- }
- /* Keep going */
- return TRUE;
- }
-
- static void new(struct Window* win)
- {
- SetRast(win->RPort, 0);
- setModified(FALSE);
- }
-
- /* Our RDArgs structure for use with ReadArgs() */
- static struct RDArgs* myrdargs = NULL;
-
- int createArgs()
- {
- if(myrdargs = AllocDosObject(DOS_RDARGS, NULL))
- {
- /* Disable prompting on stdin when "?" is the argument */
- myrdargs->RDA_Flags = RDAF_NOPROMPT;
- return TRUE;
- }
- else
- printf("Error: could not allocate args for ARexx commands\n");
- return FALSE;
- }
-
- void freeArgs()
- {
- if(myrdargs)
- FreeDosObject(DOS_RDARGS, myrdargs);
- }
-
- /* The result of a ReadArgs() while parsing commands */
- static struct RDArgs* rdargs = NULL;
-
- /* Test if a string matches a command, using ReadArgs() */
- static int isCommand(char* text, char* comm,
- char* templ, LONG* args)
- {
- int clen = strlen(comm);
- if(strnicmp(text, comm, clen) == 0)
- {
- /* Is the command followed by some whitespace? */
- if(text[clen] == ' ' || text[clen] == '\t')
- {
- int tlen = strlen(text);
- /* Set up our myrdargs so we can use ReadArgs() */
- myrdargs->RDA_Source.CS_Buffer = text+clen+1;
- myrdargs->RDA_Source.CS_Length = tlen-clen;
- myrdargs->RDA_Source.CS_CurChr = 0;
- myrdargs->RDA_DAList = NULL;
- myrdargs->RDA_Buffer = NULL;
- /* Temporarily end the string with a return... */
- /* (Needed to get ReadArgs() to work properly) */
- text[tlen] = '\n';
- rdargs = ReadArgs(templ, args, myrdargs);
- /* ... now we must reinstate the string's terminator */
- text[tlen] = '\0';
- return rdargs != NULL;
- }
- }
- return NULL;
- }
-
- static void freeCommand()
- {
- if(rdargs)
- {
- FreeArgs(rdargs);
- rdargs = NULL;
- }
- }
-
- /* The maximum number of arguments for our commands */
- #define MAX_ARGS (3)
-
- #define COMM_QUIT "QUIT"
-
- #define COMM_NEW "NEW"
-
- #define COMM_PEN "PEN"
- #define TEMPL_PEN "PEN/N"
- enum PEN_ARGS { PEN_PEN };
-
- #define COMM_DRAW "DRAW"
- #define TEMPL_DRAW "X/N,Y/N,TEXT/F"
- enum DRAW_ARGS { DRAW_X, DRAW_Y, DRAW_TEXT };
-
- /* Process an ARexx message */
- static int doARexx(struct RexxMsg* msg, struct Window* drawwin)
- {
- int going = TRUE;
- /* By default, our reply will indicate an error */
- LONG rc = 20;
- char* res = NULL;
- char* command = msg->rm_Args[0];
- /* Parse the command */
- if(stricmp(command, COMM_QUIT) == 0)
- {
- going = FALSE;
- /* We recognised the command, so set rc to zero */
- rc = 0;
- res = "Hello Painter is quitting";
- }
- else if(stricmp(command, COMM_NEW) == 0)
- {
- new(drawwin);
- rc = 0;
- res = "Display cleared";
- }
- else
- {
- LONG args[MAX_ARGS];
- int i;
- for(i=0; i<MAX_ARGS; i++)
- args[i] = NULL;
- if(isCommand(command, COMM_PEN, TEMPL_PEN, args))
- {
- /* args[0] holds the pen number to use */
- LONG* nptr = (LONG*)(args[PEN_PEN]);
- setFgPen(drawwin, *nptr);
- rc = 0;
- res = "Pen set";
- }
- else if(isCommand(command, COMM_DRAW, TEMPL_DRAW, args))
- {
- /* args[DRAW_X] and args[DRAW_Y] hold the coordinate */
- /* args[DRAW_TEXT] holds the text to be drawn */
- LONG* xptr = (LONG*)(args[DRAW_X]);
- LONG* yptr = (LONG*)(args[DRAW_Y]);
- char* text = (char*)(args[DRAW_TEXT]);
- Move(drawwin->RPort, *xptr, *yptr);
- Text(drawwin->RPort, text, strlen(text));
- setModified(TRUE);
- rc = 0;
- res = "Text drawn";
- }
- freeCommand();
- }
- replyARexxMsg(msg, rc, res);
- return going;
- }
-